﻿using System;
using System.Linq;
using Styx;
using Styx.CommonBot;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Action = Styx.TreeSharp.Action;

namespace TheFinalCall
{
    public static class Generic
    {
        // [Behavior(BehaviorType.PreCombatBuffs, priority:999)]
        // [IgnoreBehaviorCount(BehaviorType.Combat), IgnoreBehaviorCount(BehaviorType.Rest)]
        public static Composite CreateFlasksBehaviour()
        {
            return new Decorator(
                ret =>
                TheFinalCallSettings.Instance.UseAlchemyFlasks &&
                !StyxWoW.Me.HasAnyAura("Enhanced Agility", "Enhanced Intellect", "Enhanced Strength"),
                new PrioritySelector(
                    Item.UseItem(75525),
                    Item.UseItem(58149),
                    Item.UseItem(47499)));
        }

        // [Behavior(BehaviorType.Combat, priority: 999)]
        public static Composite CreateUseTrinketsBehaviour()
        {
            // Saving Settings via GUI will now force reinitialize so we can build the behaviors
            // basead upon the settings rather than continually checking the settings in the Btree
            // 
            // 

            if (TheFinalCallSettings.Instance.Trinket1Usage == TrinketUsage.Never &&
                TheFinalCallSettings.Instance.Trinket2Usage == TrinketUsage.Never)
            {
                return new Action(ret => { return RunStatus.Failure; });
            }

            var ps = new PrioritySelector();

            if (TheFinalCallSettings.IsTrinketUsageWanted(TrinketUsage.OnCooldown))
            {
                ps.AddChild(Item.UseEquippedTrinket(TrinketUsage.OnCooldown));
            }

            if (TheFinalCallSettings.IsTrinketUsageWanted(TrinketUsage.OnCooldownInCombat))
            {
                ps.AddChild(Item.UseEquippedTrinket(TrinketUsage.OnCooldownInCombat));
            }

            if (TheFinalCallSettings.IsTrinketUsageWanted(TrinketUsage.LowHealth))
            {
                ps.AddChild(new Decorator(ret => StyxWoW.Me.HealthPercent < TheFinalCallSettings.Instance.PotionHealth,
                                          Item.UseEquippedTrinket(TrinketUsage.LowHealth)));
            }

            if (TheFinalCallSettings.IsTrinketUsageWanted(TrinketUsage.LowPower))
            {
                ps.AddChild(new Decorator(ret => StyxWoW.Me.PowerPercent < TheFinalCallSettings.Instance.PotionMana,
                                          Item.UseEquippedTrinket(TrinketUsage.LowPower)));
            }

            if (TheFinalCallSettings.IsTrinketUsageWanted(TrinketUsage.CrowdControlled))
            {
                ps.AddChild(new Decorator(ret => StyxWoW.Me.IsCrowdControlled(),
                                          Item.UseEquippedTrinket(TrinketUsage.CrowdControlled)));
            }

            if (TheFinalCallSettings.IsTrinketUsageWanted(TrinketUsage.CrowdControlledSilenced))
            {
                ps.AddChild(new Decorator(ret => StyxWoW.Me.Silenced && StyxWoW.Me.IsCrowdControlled(),
                                          Item.UseEquippedTrinket(TrinketUsage.CrowdControlledSilenced)));
            }

            return ps;
        }

        // [Behavior(BehaviorType.Combat, priority: 998)]
        public static Composite CreateRacialBehaviour()
        {
            return new Throttle(TimeSpan.FromMilliseconds(250),
                                new Decorator(
                                    ret => TheFinalCallSettings.Instance.UseRacials,
                                    new PrioritySelector(
                                        new Decorator(
                                            ret =>
                                            SpellManager.CanCast("Stoneform") &&
                                            StyxWoW.Me.GetAllAuras()
                                                   .Any(a => a.Spell.Mechanic == WoWSpellMechanic.Bleeding ||
                                                             a.Spell.DispelType == WoWDispelType.Disease ||
                                                             a.Spell.DispelType == WoWDispelType.Poison),
                                            Spell.Cast("Stoneform")),
                                        new Decorator(
                                            ret =>
                                            SpellManager.CanCast("Escape Artist") &&
                                            StyxWoW.Me.HasAuraWithMechanic(WoWSpellMechanic.Rooted,
                                                                           WoWSpellMechanic.Snared),
                                            Spell.Cast("Escape Artist")),
                                        new Decorator(
                                            ret =>
                                            SpellManager.CanCast("Every Man for Himself") &&
                                            StyxWoW.Me.IsCrowdControlled(),
                                            Spell.Cast("Every Man for Himself")),
                                        new Decorator(
                                            ret =>
                                            SpellManager.CanCast("Gift of the Naaru") &&
                                            StyxWoW.Me.HealthPercent < TheFinalCallSettings.Instance.GiftNaaruHP,
                                            Spell.Cast("Gift of the Naaru")),
                                        Spell.Cast("Shadowmeld", ret => NeedShadowmeld()),
                                        Spell.BuffSelf("Lifeblood",
                                                       ret =>
                                                       !PartyBuff.WeHaveBloodlust &&
                                                       !StyxWoW.Me.HasAnyAura("Lifeblood", "Berserking")),
                                        Spell.BuffSelf("Berserking",
                                                       ret =>
                                                       !PartyBuff.WeHaveBloodlust && !StyxWoW.Me.HasAura("Lifeblood")),
                                        Spell.BuffSelf("Blood Fury")
                                        )
                                    )
                );
        }

        private static bool NeedShadowmeld()
        {
            if (!TheFinalCallSettings.Instance.ShadowmeldThreatDrop || StyxWoW.Me.Race != WoWRace.NightElf)
                return false;

            if (!SpellManager.CanCast("Shadowmeld"))
                return false;

            if (StyxWoW.Me.IsInGroup())
            {
                if (Group.MeIsTank)
                    return false;

                if (TheFinalCallRoutine.CurrentWoWContext == WoWContext.Battlegrounds)
                {
                    if (
                        !Unit.NearbyUnfriendlyUnits.Any(
                            unit =>
                            unit.CurrentTargetGuid == StyxWoW.Me.Guid &&
                            (unit.Class == WoWClass.Hunter || unit.Class == WoWClass.Mage ||
                             unit.Class == WoWClass.Priest || unit.Class == WoWClass.Warlock)))
                    {
                        return true; // since likely a ranged target
                    }
                }
                else if (!Unit.NearbyUnfriendlyUnits.Any(unit => unit.CurrentTargetGuid == StyxWoW.Me.Guid))
                {
                    return false;
                }

                if (Group.AnyTankNearby)
                    return true;
            }

            // need to add logic to wait for pats, or for PVP losing ranged targets may be enough
            return false;
        }

        // [Behavior(BehaviorType.Combat, priority: 997)]
        public static Composite CreatePotionAndHealthstoneBehavior()
        {
            return Item.CreateUsePotionAndHealthstone(TheFinalCallSettings.Instance.PotionHealth,
                                                      TheFinalCallSettings.Instance.PotionMana);
        }
    }
}